<?php
declare (strict_types=1);

namespace app\middleware;

use app\admin\library\Auth;
use http\Url;

use think\exception\HttpResponseException;
use think\facade\Config;
use think\facade\Request;
use think\facade\Route;
use think\facade\Session;
use think\facade\View;
use think\Response;

class CheckLogin
{
    protected $auth = null;

    protected $noNeedLogin = ['login'];
    protected $noNeedRight = ['index', 'logout'];

    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        $controllername = $request->controller(); //控制器名称
        $actionname = $request->action();//方法名
        $path = str_replace('.', '/', $controllername) . '/' . $actionname;
        $this->auth = Auth::instance();
        // 设置当前请求的URI
        $this->auth->setRequestUri($path);
        if (!$this->auth->match($this->noNeedLogin)) {
            if (!$this->auth->isLogin()) {
                $url = Session::get('referer');
                $url = $url ? $url : $request->url();
                if ($url == '/') {
                    return redirect('/admin/login/index');
                }
            }
            $admin = Session::get('admin');
            if ($admin) {
                $request->withHeader(array_merge(Request::header(), ['Authorization' => 'Bearer ' . $admin['token']]));
            } else {
                return redirect('/admin/login/index');
            }

            if (!$this->auth->match($this->noNeedRight)) {
                // 判断控制器和方法判断是否有对应权限
                if (!$this->auth->check($path)) {
                    $this->error(('你没有权限'), '');
                }
            }
        }
        // 设置面包屑导航数据
        $breadcrumb = $this->auth->getBreadCrumb($path);
        array_pop($breadcrumb);
        return $next($request);
    }

    /**
     * 操作错误跳转的快捷方法
     * @access protected
     * @param mixed $msg 提示信息
     * @param string $url 跳转的 URL 地址
     * @param mixed $data 返回的数据
     * @param int $wait 跳转等待时间
     * @param array $header 发送的 Header 信息
     * @return void
     * @throws HttpResponseException
     */
    protected function error($msg = '', $url = null, $data = '', $wait = 3, array $header = [])
    {

        if (is_null($url)) {

            $url = Request::isAjax() ? '' : 'javascript:history.back(-1);';
        } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) {
            $url = Route::buildUrl($url);
        }

        $type = $this->getResponseType();

        $result = [
            'code' => 0,
            'msg' => $msg,
            'data' => $data,
            'url' => $url,
            'wait' => $wait,
        ];

        if ('html' == strtolower($type)) {
            $template = Config::get('view');
            $view = Config::get('app.view_replace_str');

            $result = View::instance($template, $view)
                ->fetch(Config::get('jump.dispatch_error_tmpl'), $result);
        }

        $response = Response::create($result, $type)->header($header);

        throw new HttpResponseException($response);
    }

    /**
     * 获取当前的 response 输出类型
     * @access protected
     * @return string
     */
    protected function getResponseType()
    {
        return Request::isAjax()
            ? Config::get('app.default_ajax_return')
            : Config::get('app.default_return_type');
    }
}
